package projectmanagement.console;

import projectmanagement.models.Iteration;
import projectmanagement.models.Project;
import projectmanagement.models.Task;
import projectmanagement.models.User;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author Dmitry Toryanik
 *         <p/>
 *         Scrum handling class handles and renders
 *         menu options which relates to Scrum. Has a two custom
 *         constructors which takes the console manager class
 *         and projects handling class to traversing
 *         entire application menus.
 */
public class ScrumHandling {
    private ConsoleManager consoleManager;
    private ProjectsHandling projectsHandling;
    private Scanner scanner = new Scanner(System.in);

    ScrumHandling(ConsoleManager consoleManager, ProjectsHandling projectsHandling) {
        this.consoleManager = consoleManager;
        this.projectsHandling = projectsHandling;
    }

    ScrumHandling(ConsoleManager consoleManager) {
        this.consoleManager = consoleManager;
    }

    void createIteration(Project p) {
        System.out.println("Iteration creation...\n");

        Calendar start = Calendar.getInstance();
        Calendar finish = Calendar.getInstance();

        System.out.print("Iteration start date (MM/dd/yyyy): ");
        String startDate = scanner.nextLine();
        System.out.print("Iteration finish date (MM/dd/yyyy): ");
        String finishDate = scanner.nextLine();

        SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
        try {
            start.setTime(formatter.parse(startDate));
            finish.setTime(formatter.parse(finishDate));
        } catch (ParseException e) {
            ConsoleManager.goBackHandler("Date format exception!", scanner);
            projectsHandling.existProjectMenu(consoleManager.getManagementTool().getProjectById(p.getProjectId()));
        }

        System.out.print("Description: ");
        String description = scanner.nextLine();

        Iteration i = consoleManager.getManagementTool().createIteration(p.getProjectId(), start, finish, description);

        if (i != null) {
            ConsoleManager.goBackHandler("\nIteration was created successfully and assigned to project!", scanner);
            projectsHandling.existProjectMenu(p);
        } else {
            ConsoleManager.goBackHandler("\nIteration creation error!", scanner);
            projectsHandling.existProjectMenu(p);
        }
    }

    void createTask(Project p) {
        System.out.println("Task creation...\n");

        System.out.print("Task estimation: ");
        int estimation = -1;

        try {
            estimation = scanner.nextInt();
        } catch (InputMismatchException e) {
            ConsoleManager.goBackHandler("Estimation must be an integer!", scanner);
            projectsHandling.existProjectMenu(p);
        }

        System.out.print("Description: ");
        scanner.nextLine();
        String description = scanner.nextLine();

        Task t = consoleManager.getManagementTool().createTask(estimation, description);
        boolean assignedSuccess = consoleManager.getManagementTool().addTask(p.getProjectId(),t);

        if ((t != null) && (assignedSuccess)) {
            System.out.printf("\nTask created successfully and assigned to project %s!", p.getProjectName());
            ConsoleManager.goBackHandler("", scanner);
            projectsHandling.existProjectMenu(p);
        } else {
            ConsoleManager.goBackHandler("Task creation error!", scanner);
            projectsHandling.existProjectMenu(p);
        }
    }

    void showProjectIterations() {
        System.out.println("Project iterations searching...\n");

        System.out.print("Project name: ");
        String name = scanner.nextLine();

        int id = consoleManager.getManagementTool().getIdByProjectName(name);
        if (id == -1) {
            System.out.printf("Sorry, we have no projects by name %s!", name);
            ConsoleManager.goBackHandler("", scanner);
            consoleManager.scrumInfoMenuHandler(null);
        }

        Collection<Iteration> iterationList = consoleManager.getManagementTool().getListOfIterations(id);
        if (iterationList.size() != 0) {
            for (Iteration i : iterationList)
                System.out.println(i + "\n");

            ConsoleManager.goBackHandler("", scanner);
            consoleManager.scrumInfoMenuHandler(null);
        } else {
            ConsoleManager.goBackHandler("Sorry, we have no iterations on this project!", scanner);
            consoleManager.scrumInfoMenuHandler(null);
        }
    }

    void showProjectTasks() {
        System.out.println("Project tasks searching...\n");

        System.out.print("Project name: ");
        String name = scanner.nextLine();

        int id = consoleManager.getManagementTool().getIdByProjectName(name);
        if (id == -1) {
            System.out.printf("Sorry, we have no projects by name %s!", name);
            ConsoleManager.goBackHandler("", scanner);
            consoleManager.scrumInfoMenuHandler(null);
        }

        List<Task> tasksList = consoleManager.getManagementTool().getListOfTasks(id);
        if (tasksList.size() != 0) {
            for (Task t : tasksList)
                System.out.printf("\n%s", t);

            ConsoleManager.goBackHandler("", scanner);
            consoleManager.scrumInfoMenuHandler(null);
        } else {
            ConsoleManager.goBackHandler("Sorry, we have no tasks on this project!", scanner);
            consoleManager.scrumInfoMenuHandler(null);
        }
    }

    void assignTaskToIteration(Project p) {
        System.out.println("Assigning task to iteration...\n");

        Collection<Iteration> iterationList = consoleManager.getManagementTool().getListOfIterations(p.getProjectId());
        List<Task> taskList = consoleManager.getManagementTool().getListOfTasks(p.getProjectId());


        System.out.println("Project's iterations: ");
        System.out.println("----------------------");
        if (iterationList.size() == 0)
            System.out.println("[NO ITERATIONS]\n");
        else
            for (Iteration i : iterationList)
                System.out.println(i);

        System.out.println("Project's tasks: ");
        System.out.println("-----------------");
        if (taskList.size() == 0)
            System.out.println("[NO TASKS]\n");
        else
            for (Task t : taskList)
                System.out.printf("ID:%d %s\n", t.getId(), t);

        if ((taskList.size() == 0) || (iterationList.size() == 0)) {
            ConsoleManager.goBackHandler("", scanner);
            projectsHandling.existProjectMenu(p);
        }

        System.out.print("\nID of task that should be assigned: ");
        int taskId = -1;

        try {
            taskId = scanner.nextInt();
            boolean valid = consoleManager.getManagementTool().isTaskIdValid(p.getProjectId(), taskId);
            if (!valid) throw new Exception();
        } catch (InputMismatchException e) {
            ConsoleManager.goBackHandler("Task ID must be an integer!", scanner);
            scanner.nextLine();
            projectsHandling.existProjectMenu(p);
        } catch (Exception e) {
            ConsoleManager.goBackHandler("We have no tasks with that ID!", scanner);
            scanner.nextLine();
            projectsHandling.existProjectMenu(p);
        }


        System.out.printf("ID of iteration where task with ID=%d should be assigned: ", taskId);
        int iterationId = -1;

        try {
            iterationId = scanner.nextInt();
            boolean valid = consoleManager.getManagementTool().isIterationIdValid(p.getProjectId(), iterationId);
            if (!valid) throw new Exception();
        } catch (InputMismatchException e) {
            ConsoleManager.goBackHandler("Iteration ID must be an integer!", scanner);
            scanner.nextLine();
            projectsHandling.existProjectMenu(p);
        } catch (Exception e) {
            ConsoleManager.goBackHandler("We have no iterations with that ID!", scanner);
            scanner.nextLine();
            projectsHandling.existProjectMenu(p);
        }

        consoleManager.getManagementTool().assignTaskToIteration(p, taskId, iterationId);


        ConsoleManager.goBackHandler("\nTask assigned successfully!", scanner);
        scanner.nextLine();
        projectsHandling.existProjectMenu(p);
    }

    void showIterationsTasks(Project p) {
        System.out.printf("Iteration's tasks on project '%s'...\n", p.getProjectName());

        Collection<Iteration> iterationList = consoleManager.getManagementTool().getListOfIterations(p.getProjectId());

        if (iterationList.size() == 0) {
            ConsoleManager.goBackHandler("[NO ITERATIONS]", scanner);
            projectsHandling.existProjectMenu(p);
        } else {
            for (Iteration i : iterationList)
                System.out.printf("%s", i);
        }

        System.out.print("\nIteration ID: ");
        int id = -1;

        try {
            id = scanner.nextInt();
        } catch (InputMismatchException e) {
            ConsoleManager.goBackHandler("Iteration ID must be an integer!", scanner);
            scanner.nextLine();
            projectsHandling.existProjectMenu(p);
        }

        Iteration i = consoleManager.getManagementTool().getIterationById(p.getProjectId(), id);

        if (i != null) {
            System.out.printf("\n%s", i);
            System.out.println("-------");

            Collection<Task> iterationsTasks = i.getTasks();
            for (Task t : iterationsTasks)
                System.out.printf("%s\n", t);

            scanner.nextLine();
            ConsoleManager.goBackHandler("", scanner);
            projectsHandling.existProjectMenu(p);
        } else {
            ConsoleManager.goBackHandler("Sorry, we have no tasks assigned to this iteration or ID is wrong!", scanner);
            scanner.nextLine();
            projectsHandling.existProjectMenu(p);
        }
    }

    void assignUserToTask(Project p) {
        System.out.println("Assigning user to task....\n");

        List<Task> taskList = consoleManager.getManagementTool().getListOfTasks(p.getProjectId());

        if (taskList.size() != 0) {
            for (Task t : taskList)
                System.out.printf("ID:%d %s\n", t.getId(), t);
        } else {
            System.out.printf("We have no tasks on project '%s' yet.", p.getProjectName());
            ConsoleManager.goBackHandler("", scanner);
            projectsHandling.existProjectMenu(p);
        }

        System.out.print("\nUser name that should be assigned: ");
        String userName = scanner.nextLine();

        User u = consoleManager.getManagementTool().getUserByName(userName);

        if (u == null) {
            System.out.printf("We have no users by name %s.", userName);
            ConsoleManager.goBackHandler("", scanner);
            projectsHandling.existProjectMenu(p);
        }

        System.out.printf("\nEnter a task ID where %s should be assigned.\n", userName);
        System.out.print("ID: ");
        int taskId = -1;

        try {
            taskId = scanner.nextInt();
            boolean valid = consoleManager.getManagementTool().isTaskIdValid(p.getProjectId(), taskId);
            if (!valid) throw new Exception();
        } catch (InputMismatchException e) {
            ConsoleManager.goBackHandler("Task ID must be an integer!", scanner);
            scanner.nextLine();
            projectsHandling.existProjectMenu(p);
        } catch (Exception e) {
            ConsoleManager.goBackHandler("We have no tasks with this ID!", scanner);
            scanner.nextLine();
            projectsHandling.existProjectMenu(p);
        }

        consoleManager.getManagementTool().assignUserToProject(u.getId(), p.getProjectId());
        if (consoleManager.getManagementTool().assignUserToTask(p.getProjectId(), taskId, u)) {
            System.out.printf("User assigned successfully to project %scanner and task with ID=%d. ", p.getProjectName(), taskId);
            ConsoleManager.goBackHandler("", scanner);
            scanner.nextLine();
            projectsHandling.existProjectMenu(p);
        } else {
            ConsoleManager.goBackHandler("Assigning error!", scanner);
            projectsHandling.existProjectMenu(p);
        }

    }

}
